/* memory.h
   By: Samuel Ferguson
   Date created: March 6th 2011
   Date modified: March 6th 2011
*/

#ifndef _XXXOS_MEMORY_H
#define _XXXOS_MEMORY_H
#include <init.h>
/*********************************/
/*** Typedefs ********************/
/*********************************/
typedef long Alignment;

/*********************************/
/*** Enums * *********************/
/*********************************/

/* Every process is given 1MB of ram for heap and stack space */
enum {process_size = 1048576};

/* size of the kernel */
enum {KERNEL_SIZE = 1048576};

/*********************************/
/*** Structs *********************/
/*********************************/

/* On the freelist, every block has a header specifying
   the size of the block, with a link to the next block */
union block_header{
  struct {                     /* This structure was inspired by section*/
    union block_header *next;  /* 8.7 of K&R's "The C Programming */
    unsigned long size;        /* Language" - Second edition */
  } s;
  Alignment alignment_forcer;
};

/* mm_struct is for memory maps of a program */
struct mm_struct {
  void* start_stack; /* Stack grows down */

  void* mmap_base;   /* Memory mapping segment */

  void* brk;         /* The heap overflow line */
  void* start_brk;   /* The beginning of the heap */


  /**** CURRENTLY UNUSED ** APRIL 1st 2011 *********************/
  void* end_data;    /* The end of the data segment and
				beginning of BSS */
  void* start_data;  /* The beginning of the data segement */
  void* end_code;    /* The end of the text segment */
  void* start_code;  /* The beginning of the text segment */
  /************************************(************************/
};

/*********************************/
/*** Functions *******************/
/*********************************/

/* Function malloc
   unsigned -> void*
   Pre: size is the size requested for allocation
   Post: A piece of RAM is allocated
   Returns: A pointer to the beginning of the allocation
            NULL on failure
*/
void* malloc(unsigned size);

/* Function free
   void* -> void
   Pre: pointer is a pointer to the RAM to be freed
   Post: The memory block is freed
   Returns: nothing
*/
void free(void* pointer);

/* Function allocate_process
   void -> struct mm_struct
   Pre: free_list is initialized by init_mem()
   Post: an block is removed from free_list and prepared for a process
   Returns: a newly allocated and initialized mm_struct for process
   Notes: At the moment this only allocates memory for stack and heap
*/
struct mm_struct* allocate_process();

/* Function mm_init
   struct mm_struct -> union block_header -> void
   Pre: process is at a slight offset from boxy. both are contained
        in a block of memory
   Post: an mm_struct is initialized for a process
   Returns: the initialized mm_struct
*/
struct mm_struct *mm_init(struct mm_struct *process, void *boxy);

/* Function init_mem
   void -> void
   This function is called by kmain() to initialize the free_list
   Pre: nothing
   Post: the free_list is initialized
   Return: nothing
*/
void init_mem(void);

/* Function make_block
   struct e820_t -> union block_header
   Pre: 
   Post:
   Return: block header made out of the e820 entry 
*/
union block_header *make_block(struct e820_t entry);

/* Function free_list_add
   union block_header -> void
   A helper function for init_mem()
   Pre: boxy is a union block_header
   Post: boxy is added to the free_list
   Return: nothing
*/
void free_list_add(union block_header *boxy);

/* Function free_process
   union block_header -> void
   Pre: boxy is a union block_header which is no longer needed
   Post: memory is regained by the free_list
   Return: nothing
*/
void free_process(union block_header *boxy);

/* Function free_merge
   union block_header -> void
   A helper function for free_process().
   Pre: boxy is a union block_header with a potential to be merged
        with the block it points to
   Post: contiguous blocks are merged
   Return: Nothing
*/
void free_merge(union block_header *boxy);

#endif /* _XXXOS_MEMORY_H */
